00001 // Emacs Mode Line: -*- Mode:c++;-*- 00002 // ------------------------------------------------------------- 00003 /* 00004 * Copyright (c) 2013 Battelle Memorial Institute 00005 * Licensed under modified BSD License. A copy of this license can be found 00006 * in the LICENSE file in the top level directory of this distribution. 00007 */ 00008 // ------------------------------------------------------------- 00009 // ------------------------------------------------------------- 00010 /** 00011 * @file vector_interface.hpp 00012 * @author William A. Perkins 00013 * @date 2015-07-24 08:50:39 d3g096 00014 * 00015 * @brief 00016 * 00017 * 00018 */ 00019 // ------------------------------------------------------------- 00020 // ------------------------------------------------------------- 00021 // Created October 20, 2014 by William A. Perkins 00022 // Last Change: 2013-05-03 12:23:12 d3g096 00023 // ------------------------------------------------------------- 00024 00025 00026 #ifndef _vector_interface_hpp_ 00027 #define _vector_interface_hpp_ 00028 00029 00030 00031 #include "gridpack/math/implementation_visitable.hpp" 00032 00033 namespace gridpack { 00034 namespace math { 00035 00036 // ------------------------------------------------------------- 00037 // Abstract class VectorInterface 00038 // ------------------------------------------------------------- 00039 /** 00040 * This defines the basic interface for vectors. 00041 * 00042 */ 00043 template<typename T, typename I = int> 00044 class BaseVectorInterface 00045 : public ImplementationVisitable 00046 { 00047 public: 00048 00049 typedef T TheType; /**< The numeric type used */ 00050 typedef I IdxType; /**< The size/index type used */ 00051 00052 /// Default constructor. 00053 BaseVectorInterface(void) 00054 : ImplementationVisitable() 00055 {} 00056 00057 /// Destructor 00058 ~BaseVectorInterface(void) 00059 {} 00060 00061 /// Get the global length 00062 /** 00063 * 00064 * @return global vector length 00065 */ 00066 IdxType size(void) const 00067 { 00068 return this->p_size(); 00069 } 00070 00071 /// Get the local length 00072 /** 00073 * 00074 * @return local vector length 00075 */ 00076 IdxType localSize(void) const 00077 { 00078 return this->p_localSize(); 00079 } 00080 00081 /// Get the local min/max global indexes 00082 /** 00083 * @e Local. 00084 * 00085 * The minimum index in the first global (0-based) index owned by 00086 * the local process. The maximum is one more than the last global 00087 * index owned. An example of usage: 00088 * 00089 \code{.cpp} 00090 int lo, hi; 00091 my_vector.local_index_range(lo, hi); 00092 for (int i = lo; i < hi; ++i) { 00093 ComplexType x; 00094 x = ...; 00095 v.setElement(i, x); 00096 } 00097 \endcode 00098 * 00099 * @param lo first (0-based) index of locally owned elements 00100 * @param hi one more than the last (0-based) index of locally owned elements 00101 */ 00102 void localIndexRange(IdxType& lo, IdxType& hi) const 00103 { 00104 return this->p_localIndexRange(lo, hi); 00105 } 00106 00107 /// Set an individual element 00108 /** 00109 * @e Local. 00110 * 00111 * This overwrites the value at the specified index. ready() must 00112 * be called after all setElement() calls and before using the 00113 * vector. 00114 * 00115 * @param i element global (0-based) index 00116 * @param x value to place in vector 00117 */ 00118 void setElement(const IdxType& i, const TheType& x) 00119 { 00120 this->p_setElement(i, x); 00121 } 00122 00123 /// Set a range of elements (lo to hi-1) 00124 /** 00125 * @e Local. 00126 * 00127 * An example that fills the locally owned part of the vector: 00128 * \code{.cpp} 00129 * Vector v(...); 00130 * int lo, hi; 00131 * v.local_index_range(lo, hi); 00132 * std::vector<ComplexType> x(v.local_size()) 00133 * // fill x with appropriate values 00134 * v.setElement_range(lo, hi, &x[0]); 00135 * \endcode 00136 * 00137 * @param lo lowest global (0-based) index to fill 00138 * @param hi one more than the highest global (0-based) index to fill 00139 * @param x array of hi - lo values 00140 */ 00141 void setElementRange(const IdxType& lo, const IdxType& hi, TheType *x) 00142 { 00143 this->p_setElementRange(lo, hi, x); 00144 } 00145 00146 /// Set an several elements 00147 /** 00148 * @e Local. 00149 * 00150 * This places (overwrites) several elements, with arbitrary 00151 * indexes, in the vector. ready() must be called after all 00152 * setElement() calls and before using the vector. 00153 * 00154 * @param n number of elements to place in vector 00155 * @param i pointer to an array of @c n global (0-based) indexes 00156 * @param x pointer to an arry 00157 */ 00158 void setElements(const IdxType& n, const IdxType *i, const TheType *x) 00159 { 00160 this->p_setElements(n, i, x); 00161 } 00162 00163 /// Add to an individual element 00164 /** 00165 * @e Local. 00166 * 00167 * 00168 * 00169 * @param i 00170 * @param x 00171 */ 00172 void addElement(const IdxType& i, const TheType& x) 00173 { 00174 this->p_addElement(i, x); 00175 } 00176 00177 /// Add to an several elements 00178 /** 00179 * @e Local. 00180 * 00181 * 00182 * 00183 * @param n 00184 * @param i 00185 * @param x 00186 */ 00187 void addElements(const IdxType& n, const IdxType *i, const TheType *x) 00188 { 00189 this->p_addElements(n, i, x); 00190 } 00191 00192 /// Add to a range of elements (lo to hi-1) 00193 /** 00194 * @e Local. 00195 * 00196 * An example that adds to the the locally owned part of the vector: 00197 * \code{.cpp} 00198 * Vector v(...); 00199 * int lo, hi; 00200 * v.local_index_range(lo, hi); 00201 * std::vector<ComplexType> x(v.local_size()) 00202 * // fill x with appropriate values 00203 * v.addElement_range(lo, hi, &x[0]); 00204 * \endcode 00205 * 00206 * @param lo lowest global (0-based) index to fill 00207 * @param hi one more than the highest global (0-based) index to fill 00208 * @param x array of hi - lo values 00209 */ 00210 void addElementRange(const IdxType& lo, const IdxType& hi, TheType *x) 00211 { 00212 this->p_addElementRange(lo, hi, x); 00213 } 00214 00215 /// Get an individual element 00216 /** 00217 * @e Local. 00218 * 00219 * Only local values may be retreived with this method. 00220 * 00221 * @param i element's global, 0-based index 00222 * @param x element's value 00223 */ 00224 void getElement(const IdxType& i, TheType& x) const 00225 { 00226 this->p_getElement(i, x); 00227 } 00228 00229 /// Get an several elements 00230 /** 00231 * @e Local. 00232 * 00233 * Only local values may be retreived with this method. 00234 * 00235 * 00236 * @param n number of elements to get 00237 * @param i array of @c n global, 0-based indexes 00238 * @param x array of @c n values 00239 */ 00240 void getElements(const IdxType& n, const IdxType *i, TheType *x) const 00241 { 00242 this->p_getElements(n, i, x); 00243 } 00244 00245 /// Get a range of elements (lo to hi-1) 00246 /** 00247 * @e Local. 00248 * 00249 * The elements whose indexes range from @c lo to @c hi-1 are 00250 * retreived. Only local values may be retreived with this method. 00251 * The length of the @c x array must be at least @c "hi - lo" 00252 * 00253 * @param lo lowest element index 00254 * @param hi one more than the highest element index 00255 * @param x existing array of values to be filled with element values 00256 */ 00257 void getElementRange(const IdxType& lo, const IdxType& hi, TheType *x) const 00258 { 00259 this->p_getElementRange(lo, hi, x); 00260 } 00261 00262 /// Get all of vector elements (on all processes) 00263 /** 00264 * @e Collective. 00265 * 00266 * This is an all gather operation and consequently will be slow. 00267 * All of this vector's elements are gathered on all processes and 00268 * placed in the in the specified array. 00269 * 00270 * 00271 * @param x array of size() length to be filled with values 00272 */ 00273 void getAllElements(TheType *x) const 00274 { 00275 this->p_getAllElements(x); 00276 } 00277 00278 00279 /// Make all the elements zero 00280 void zero(void) 00281 { 00282 this->p_zero(); 00283 } 00284 00285 /// Make all the elements the specified value 00286 void fill(const TheType& v) 00287 { 00288 this->p_fill(v); 00289 } 00290 00291 /// Scale all elements by a single value 00292 void scale(const TheType& x) 00293 { 00294 this->p_scale(x); 00295 } 00296 00297 /// Compute the vector L1 norm (sum of absolute value) 00298 double norm1(void) const 00299 { 00300 return this->p_norm1(); 00301 } 00302 00303 /// Compute the vector L2 norm (root of sum of squares) 00304 double norm2(void) const 00305 { 00306 return this->p_norm2(); 00307 } 00308 00309 /// Compute the infinity (or maximum) norm 00310 double normInfinity(void) const 00311 { 00312 return this->p_normInfinity(); 00313 } 00314 00315 /// Replace all elements with its absolute value (complex magnitude) 00316 void abs(void) 00317 { 00318 this->p_abs(); 00319 } 00320 00321 /// Replace all elements with their real part 00322 void real(void) 00323 { 00324 this->p_real(); 00325 } 00326 00327 /// Replace all elements with their imaginary part 00328 void imaginary(void) 00329 { 00330 this->p_imaginary(); 00331 } 00332 00333 /// Replace all elements with their complex conjugate 00334 void conjugate(void) 00335 { 00336 this->p_conjugate(); 00337 } 00338 00339 /// Replace all elements with its exponential 00340 void exp(void) 00341 { 00342 this->p_exp(); 00343 } 00344 00345 /// Replace all elements with its reciprocal 00346 void reciprocal(void) 00347 { 00348 this->p_reciprocal(); 00349 } 00350 00351 /// Make this instance ready to use 00352 void ready(void) 00353 { 00354 this->p_ready(); 00355 } 00356 00357 /// Print to named file or standard output 00358 /** 00359 * @e Collective. 00360 * 00361 * 00362 * 00363 * The format is dependent on the specific vector implementation. 00364 * 00365 * @param filename optional file 00366 */ 00367 void print(const char* filename = NULL) const 00368 { 00369 this->p_print(filename); 00370 } 00371 00372 /// Save, in MatLAB format, to named file (collective) 00373 /** 00374 * @e Collective. 00375 * 00376 * 00377 * 00378 * @param filename 00379 */ 00380 void save(const char *filename) const 00381 { 00382 this->p_save(filename); 00383 } 00384 00385 /// Load from a named file of whatever binary format the math library uses 00386 /** 00387 * @e Collective. 00388 * 00389 * The underlying math library generally supports some way to save a 00390 * Vector to a file. This will load elements from a file of that 00391 * format. 00392 * 00393 * @param filename 00394 */ 00395 void loadBinary(const char *filename) 00396 { 00397 this->p_loadBinary(filename); 00398 } 00399 00400 00401 /// Save to named file in whatever binary format the math library uses 00402 /** 00403 * @e Collective. 00404 * 00405 * The underlying math library generally supports some way to save a 00406 * Vector to a file. This routine uses whatever format that can be 00407 * read by ::loadBinary(). 00408 * 00409 * @param filename 00410 */ 00411 void saveBinary(const char *filename) const 00412 { 00413 this->p_saveBinary(filename); 00414 } 00415 00416 protected: 00417 00418 /// Get the global vector length (specialized) 00419 virtual IdxType p_size(void) const = 0; 00420 00421 /// Get the size of the vector local part (specialized) 00422 virtual IdxType p_localSize(void) const = 0; 00423 00424 /// Get the local min/max global indexes (specialized) 00425 virtual void p_localIndexRange(IdxType& lo, IdxType& hi) const = 0; 00426 00427 /// Set an individual element (specialized) 00428 virtual void p_setElement(const IdxType& i, const TheType& x) = 0; 00429 00430 /// Set an several elements (specialized) 00431 virtual void p_setElements(const IdxType& n, const IdxType *i, const TheType *x) = 0; 00432 00433 /// Get a range of elements (lo to hi-1) (specialized) 00434 virtual void p_setElementRange(const IdxType& lo, const IdxType& hi, TheType *x) = 0; 00435 00436 /// Add to an individual element (specialized) 00437 virtual void p_addElement(const IdxType& i, const TheType& x) = 0; 00438 00439 /// Add to an several elements (specialized) 00440 virtual void p_addElements(const IdxType& n, const IdxType *i, const TheType *x) = 0; 00441 00442 /// Add to a range of elements (lo to hi-1) (specialized) 00443 virtual void p_addElementRange(const IdxType& lo, const IdxType& hi, TheType *x) = 0; 00444 00445 /// Get an individual element (specialized) 00446 virtual void p_getElement(const IdxType& i, TheType& x) const = 0; 00447 00448 /// Get an several elements (specialized) 00449 virtual void p_getElements(const IdxType& n, const IdxType *i, TheType *x) const = 0; 00450 00451 /// Get a range of elements (lo to hi-1) (specialized) 00452 virtual void p_getElementRange(const IdxType& lo, const IdxType& hi, TheType *x) const = 0; 00453 00454 /// Get all of vector elements (on all processes) 00455 virtual void p_getAllElements(TheType *x) const = 0; 00456 00457 /// Make all the elements zero (specialized) 00458 virtual void p_zero(void) = 0; 00459 00460 /// Fill all the elements with the specified value (specialized) 00461 virtual void p_fill(const TheType& v) = 0; 00462 00463 /// Scale all elements by a single value (specialized) 00464 virtual void p_scale(const TheType& x) = 0; 00465 00466 /// Compute the vector L1 norm (sum of absolute value) (specialized) 00467 virtual double p_norm1(void) const = 0; 00468 00469 /// Compute the vector L2 norm (root of sum of squares) (specialized) 00470 virtual double p_norm2(void) const = 0; 00471 00472 /// Compute the vector infinity (or maximum) norm (specialized) 00473 virtual double p_normInfinity(void) const = 0; 00474 00475 /// Replace all elements with its absolute value (specialized) 00476 virtual void p_abs(void) = 0; 00477 00478 /// Replace all elements with their real part (specialized) 00479 virtual void p_real(void) = 0; 00480 00481 /// Replace all elements with their imaginary part (specialized) 00482 virtual void p_imaginary(void) = 0; 00483 00484 /// Replace all elements with their complex conjugate 00485 virtual void p_conjugate(void) = 0; 00486 00487 /// Replace all elements with its exponential (specialized) 00488 virtual void p_exp(void) = 0; 00489 00490 /// Replace all elements with its reciprocal (specialized) 00491 virtual void p_reciprocal(void) = 0; 00492 00493 /// Make this instance ready to use 00494 virtual void p_ready(void) = 0; 00495 00496 /// Print to named file or standard output 00497 virtual void p_print(const char* filename = NULL) const = 0; 00498 00499 /// Save, in MatLAB format, to named file (collective) 00500 virtual void p_save(const char *filename) const = 0; 00501 00502 /// Load from a named file of whatever binary format the math library uses 00503 virtual void p_loadBinary(const char *filename) = 0; 00504 00505 /// Save to named file in whatever binary format the math library uses 00506 virtual void p_saveBinary(const char *filename) const = 0; 00507 00508 }; 00509 00510 00511 00512 00513 00514 } // namespace math 00515 } // namespace gridpack 00516 00517 00518 #endif